package cz.data.domain.metadata.controller;

import cz.data.common.base.BaseController;
import cz.data.common.base.BaseResponse;
import cz.data.common.base.SimpleDataResponse;
import cz.data.common.core.DataConstant;
import cz.data.common.core.JsonPage;
import cz.data.common.utils.ThrowableUtil;
import cz.data.common.validate.ValidationGroups;
import org.apache.commons.lang3.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cz.data.domain.metadata.mapstruct.MetadataColumnMapper;
import cz.data.domain.metadata.model.dto.MetadataColumnDto;
import cz.data.domain.metadata.model.entity.MetadataColumnEntity;
import cz.data.domain.metadata.model.query.MetadataColumnQuery;
import cz.data.domain.metadata.model.vo.MetadataColumnVo;
import cz.data.domain.metadata.model.vo.MetadataTreeVo;
import cz.data.domain.metadata.service.MetadataColumnService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Api(tags = {"元数据列"})
@RestController
@RequestMapping("/columns")
public class MetadataColumnController extends BaseController {

    @Autowired
    private MetadataColumnService metadataColumnService;

    @Autowired
    private MetadataColumnMapper metadataColumnMapper;

    @ApiOperation(value = "元数据列-获取表包含的列")
    @GetMapping("/table/{id}")
    public List<MetadataColumnEntity> getMetadataColumnByTableId(@PathVariable("id") String id) {
        QueryWrapper<MetadataColumnEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MetadataColumnEntity::getTableId, id);
        return metadataColumnService.list(queryWrapper);
    }

    @ApiOperation(value = "元数据列-详情", notes = "根据url的id来获取详细信息")
    @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path")
    @GetMapping("/{id}")
    public SimpleDataResponse<MetadataColumnVo> getDataMetadataColumnById(@PathVariable String id) {
        MetadataColumnEntity metadataColumnEntity = metadataColumnService.getMetadataColumnById(id);
        return new SimpleDataResponse<>(metadataColumnMapper.toVO(metadataColumnEntity));
    }

    @ApiOperation(value = "元数据列-列表", notes = "")
    @GetMapping("/list")
    public SimpleDataResponse<List<MetadataColumnVo>> getDataMetadataColumnList(MetadataColumnQuery metadataColumnQuery) {
        List<MetadataColumnEntity> list = metadataColumnService.getDataMetadataColumnList(metadataColumnQuery);
        List<MetadataColumnVo> collect = list.stream().map(metadataColumnMapper::toVO).collect(Collectors.toList());
        return new SimpleDataResponse<>(collect);
    }

    @ApiOperation(value = "元数据列-分页", notes = "分页查询信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "dataMetadataColumnQuery", value = "查询实体dataMetadataColumnQuery", required = true, dataTypeClass = MetadataColumnQuery.class)
    })
    @GetMapping("/page")
    public SimpleDataResponse<JsonPage<MetadataColumnVo>> getDataMetadataColumnPage(MetadataColumnQuery metadataColumnQuery) {
        QueryWrapper<MetadataColumnEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(metadataColumnQuery.getColumnName()), "c.column_name", metadataColumnQuery.getColumnName());
        queryWrapper.eq(StringUtils.isNotBlank(metadataColumnQuery.getSourceId()), "c.source_id", metadataColumnQuery.getSourceId());
        queryWrapper.eq(StringUtils.isNotBlank(metadataColumnQuery.getTableId()), "c.table_id", metadataColumnQuery.getTableId());
        IPage<MetadataColumnEntity> page = metadataColumnService.pageWithAuth(new Page<>(metadataColumnQuery.getPageNum(), metadataColumnQuery.getPageSize()), queryWrapper);
        List<MetadataColumnVo> collect = page.getRecords().stream().map(metadataColumnMapper::toVO).collect(Collectors.toList());
        JsonPage<MetadataColumnVo> jsonPage = new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect);
        return new SimpleDataResponse<>(jsonPage);
    }

    @ApiOperation(value = "元数据列-添加", notes = "根据dataMetadataColumn对象添加信息")
    @ApiImplicitParam(name = "dataMetadataColumn", value = "详细实体dataMetadataColumn", required = true, dataType = "DataMetadataColumnDto")
    @PostMapping()
    public SimpleDataResponse<MetadataColumnVo> saveDataMetadataColumn(@RequestBody @Validated({ValidationGroups.Insert.class}) MetadataColumnDto dataMetadataColumn) {
        MetadataColumnEntity metadataColumnEntity = metadataColumnService.saveMetadataColumn(dataMetadataColumn);
        return new SimpleDataResponse<>(metadataColumnMapper.toVO(metadataColumnEntity));
    }

    @ApiOperation(value = "元数据列-修改", notes = "根据url的id来指定修改对象，并根据传过来的信息来修改详细信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path"),
            @ApiImplicitParam(name = "dataMetadataColumn", value = "详细实体dataMetadataColumn", required = true, dataType = "DataMetadataColumnDto")
    })
    @PutMapping("/{id}")
    public SimpleDataResponse<MetadataColumnVo> updateDataMetadataColumn(@PathVariable String id, @RequestBody @Validated({ValidationGroups.Update.class}) MetadataColumnDto dataMetadataColumn) {
        MetadataColumnEntity metadataColumnEntity = metadataColumnService.updateMetadataColumn(dataMetadataColumn);
        return new SimpleDataResponse<>(metadataColumnMapper.toVO(metadataColumnEntity));
    }

    @ApiOperation(value = "元数据列-修正", notes = "字段修正")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "columnKey", value = "columnKey", required = true, dataType = "String"),
            @ApiImplicitParam(name = "columnComment", value = "columnComment", required = true, dataType = "String"),
    })
    @PutMapping("/amend")
    public BaseResponse amendDataMetadataColumn(@RequestBody MetadataColumnDto request) {
        MetadataColumnDto column = new MetadataColumnDto();
        column.setId(request.getId());
        DataConstant.TrueOrFalse columnKey = ThrowableUtil.callable(() -> DataConstant.TrueOrFalse.parse(request.getColumnKey()));
        if (Objects.nonNull(columnKey)) {
            column.setColumnKey(columnKey.getKey());
        }
        column.setColumnComment(request.getColumnComment());
        metadataColumnService.updateMetadataColumn(column);
        return BaseResponse.success();
    }

    @ApiOperation(value = "元数据列-删除", notes = "根据url的id来指定删除对象")
    @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path")
    @DeleteMapping("/{id}")
    public BaseResponse deleteDataMetadataColumnById(@PathVariable String id) {
        metadataColumnService.deleteMetadataColumnById(id);
        return BaseResponse.success();
    }

    @ApiOperation(value = "元数据列-批量删除", notes = "根据url的ids来批量删除对象")
    @ApiImplicitParam(name = "ids", value = "ID集合", required = true, dataType = "List", paramType = "path")
    @DeleteMapping("/batch/{ids}")
    public BaseResponse deleteDataMetadataColumnBatch(@PathVariable List<String> ids) {
        metadataColumnService.deleteMetadataColumnBatch(ids);
        return BaseResponse.success();
    }

    @ApiOperation(value = "元数据列-获取层级树", notes = "根据url的层级来获取树对象")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "level", value = "层级", required = true, dataType = "String", paramType = "path"),
            @ApiImplicitParam(name = "metadataColumnQuery", value = "查询实体metadataColumnQuery", required = false, dataType = "MetadataColumnQuery")
    })
    @GetMapping("/tree/{level}")
    public SimpleDataResponse<List<MetadataTreeVo>> getDataMetadataTree(@PathVariable String level, MetadataColumnQuery metadataColumnQuery) {
        List<MetadataTreeVo> list = metadataColumnService.getDataMetadataTree(level, metadataColumnQuery);
        return new SimpleDataResponse<>(list);
    }
}
